
#include "stdafx.h"
#include "EditCtrlEx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif



CEditCtrlEx::CEditCtrlEx()
{
	m_pEditListener = NULL;
	m_bState = FALSE;
	m_selStart	= 0xffffffff;
	m_selEnd	= 0xffffffff;
}

CEditCtrlEx::~CEditCtrlEx()
{
}


BEGIN_MESSAGE_MAP(CEditCtrlEx, CEdit)
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_WM_MBUTTONDBLCLK()
	ON_WM_CONTEXTMENU()
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CEditCtrlEx message handlers

void CEditCtrlEx::SetListener( CEditCtrlEx* pEdit )
{
	m_pEditListener = pEdit;
}

void CEditCtrlEx::ClearSelectState()
{
	if (m_pEditListener)
	{
		GetSel(m_selStart, m_selEnd);
		if (m_selStart == m_selEnd)
		{	
			m_pEditListener->SetSel(0,0);
		}
	}
}

void CEditCtrlEx::SetSelectState()
{
	int selStart, selEnd;
	GetSel(selStart, selEnd);
	if (selStart != m_selStart || selEnd != m_selEnd)
	{	
		m_selStart = selStart;
		m_selEnd = selEnd;
		HandleListener();
	}
}

void CEditCtrlEx::OnLButtonDown(UINT nFlags, CPoint point) 
{
	CEdit::OnLButtonDown(nFlags, point);
}

void CEditCtrlEx::OnMouseMove( UINT nFlags, CPoint point )
{
	SetSelectState();
	CEdit::OnMouseMove(nFlags, point);
}

void CEditCtrlEx::OnLButtonUp( UINT nFlags, CPoint point )
{
	ClearSelectState();
	CEdit::OnLButtonUp(nFlags, point);
}

void CEditCtrlEx::OnLButtonDblClk( UINT nFlags, CPoint point )
{
	SetSelectState();
	CEdit::OnLButtonDblClk(nFlags, point);
}

void CEditCtrlEx::OnContextMenu( CWnd* pWnd, CPoint point )
{
	ClearSelectState();
	CEdit::OnContextMenu(pWnd, point);
	SetSelectState();
}

CString CEditCtrlEx::FormatHex(PBYTE data, DWORD datalen)
{
	CString str;
	TCHAR buf[100];
	TCHAR * tbl = L"0123456789ABCDEF";
	int addr = 0;
	for (;datalen; data=data+16, addr=addr+16, datalen = datalen - min(datalen, 16))
	{
		TCHAR * p = buf;
// 		*p++ = tbl[(addr >> 20) & 0xf];
// 		*p++ = tbl[(addr >> 16) & 0xf];
// 		*p++ = tbl[(addr >> 12) & 0xf];
// 		*p++ = tbl[(addr >>  8) & 0xf];
// 		*p++ = tbl[(addr >>  4) & 0xf];
// 		*p++ = tbl[(addr >>  0) & 0xf];
// 		*p++ = ' ';
// 		*p++ = ' ';
// 		p[48] = ' ';
// 		p[49] = ' ';
		for (DWORD i=0; i<16; ++i)
		{
			if (i < datalen)
			{
				p[i*3+0] = tbl[data[i] >>  4];
				p[i*3+1] = tbl[data[i] & 0xf];
				if (i < 15)
					p[i*3+2] = /*(i == 7) ? '-' :*/ ' ';
				//p[50+i] = (data[i]>0x20 && data[i]<0x7f) ? data[i] : '.';
			}
// 			else
// 			{
// 				p[i*3+0] = ' ';
// 				p[i*3+1] = ' ';
// 				p[i*3+2] = ' ';
// 				p[50+i] = ' ';
// 			}
		}
		if (datalen >= 16)
		{
			p += 15*3+2;
		}
		else
		{
			p += (datalen-1)*3+2;
		}
		
		*p++ = '\r';
		*p++ = '\n';
		*p++ = 0;
		str += buf;
	}
	return str;
}

void CHexEditCtrl::HandleListener()
{
	CString strText;
	m_pEditListener->GetWindowText(strText);
	int nSize = wcslen(strText);
	int n = WideCharToMultiByte(CP_ACP, 0, strText.GetBuffer(), nSize, NULL, 0, 0, 0);
	strText.ReleaseBuffer();
	char* buffer = new char[n+1];
	WideCharToMultiByte(CP_ACP, 0, strText.GetBuffer(), int(nSize), buffer, int(n), 0, 0);
	strText.ReleaseBuffer();
	int selStart = m_selStart/49*16 + (m_selStart%49+2)/3;
	int selEnd = m_selEnd/49*16 + m_selEnd%49/3 + m_selEnd%49%3/2;

	int selTextStart = MultiByteToWideChar(CP_ACP, 0, buffer, selStart, 0, NULL);
	int selTextEnd = MultiByteToWideChar(CP_ACP, 0, buffer, selEnd, NULL, 0);
	m_pEditListener->SetSel(selTextStart, selTextEnd, FALSE);

	delete buffer;
}

void CTextEditCtrl::HandleListener()
{
	CString strText;
	GetWindowText(strText);
	int selStart = WideCharToMultiByte(CP_ACP, 0, strText.GetBuffer(), int(m_selStart), NULL, 0, 0, 0);
	strText.ReleaseBuffer();
	int selEnd = WideCharToMultiByte(CP_ACP, 0, strText.GetBuffer(), int(m_selEnd), NULL, 0, 0, 0);
	strText.ReleaseBuffer();
	
	int leaS = selStart%16;
	int leaE = selEnd%16-1;
	m_pEditListener->SetSel(selStart/16*49+leaS*3, selEnd/16*49+(leaE>=0?(leaE*3+2):0), FALSE);
}